Function.RegisterNamespace("System.EnvironmentStrategy");

System.EnvironmentStrategy.Node=function(){
    var _exec=null;

    // IEnvironmentStrategy members
    this.Execute=function(command,parameters,voidOutput){
        if(!_exec)_exec=require("child_process").execSync;
        var result=_exec([command].concat(parameters).join(' '), function(error, stdout, stderr) { 
            result=stdout||stderr; 
        });
        if(!voidOutput)return result+'';
    };

    this.Exit=function(errorCode){
        process.reallyExit(errorCode);
    };

    this.GetNewLine=function(){
        return "\n";
    };

    this.GetParameters=function(){
        var args={
            named:{},
            unnamed:[]
        };
        var params=process.argv;
        // First arg is node, second is js file
        for(var i=2;i<params.length;i++){
            var param=String.Trim(params[i]+'');
            if(String.StartsWith(param,'/')&&String.Contains(param,':')){
                param=String.TrimStart(param,'/').split(':');
                args.named[param[0].toLowerCase()]=param.slice(1).join(':');
            }else args.unnamed.push(param);
        }
        return args;
    };
    
    this.GetWorkingDirectory=function(){
        return System.IO.Path.Normalize(process.cwd());
    };

    this.Write=function(message1,message2,messageN){
        process.stdout.write(Array.prototype.slice.call(arguments,0).join(''));
    };
    
    this.WriteError=function(message1,message2,messageN){
        process.stderr.write(Array.prototype.slice.call(arguments,0).join(''));
    };

    // IStrategySpecification members
    this.IsSatisfiedBy=function(candidate){
        return (Object.Global()==Object.Global().global&&typeof(process)!="undefined"&&typeof(require)=="function");
    };
};

System.EnvironmentStrategy.Node.Implement(System.EnvironmentStrategy.IEnvironmentStrategy,'System.EnvironmentStrategy.Node');
System.EnvironmentStrategy.Node.Implement(System.Script.Strategy.IStrategySpecification,'System.EnvironmentStrategy.Node');

System.Environment.Strategies.Add(System.EnvironmentStrategy.Node);
